home *** CD-ROM | disk | FTP | other *** search
/ Languguage OS 2 / Languguage OS II Version 10-94 (Knowledge Media)(1994).ISO / gnu / nihcl-30.lha / nihcl-3.0 / lib / Time.c < prev    next >
C/C++ Source or Header  |  1990-05-19  |  7KB  |  323 lines

  1. /* Time.c -- implementation of class Time
  2.  
  3.     THIS SOFTWARE FITS THE DESCRIPTION IN THE U.S. COPYRIGHT ACT OF A
  4.     "UNITED STATES GOVERNMENT WORK".  IT WAS WRITTEN AS A PART OF THE
  5.     AUTHOR'S OFFICIAL DUTIES AS A GOVERNMENT EMPLOYEE.  THIS MEANS IT
  6.     CANNOT BE COPYRIGHTED.  THIS SOFTWARE IS FREELY AVAILABLE TO THE
  7.     PUBLIC FOR USE WITHOUT A COPYRIGHT NOTICE, AND THERE ARE NO
  8.     RESTRICTIONS ON ITS USE, NOW OR SUBSEQUENTLY.
  9.  
  10. Author:
  11.     K. E. Gorlen
  12.     Bg. 12A, Rm. 2033
  13.     Computer Systems Laboratory
  14.     Division of Computer Research and Technology
  15.     National Institutes of Health
  16.     Bethesda, Maryland 20892
  17.     Phone: (301) 496-1111
  18.     uucp: uunet!nih-csl!kgorlen
  19.     Internet: kgorlen@alw.nih.gov
  20.     December, 1985
  21.  
  22. Function:
  23.     
  24. Provides an object that represents a Time, stored as the number of
  25. seconds since January 1, 1901, GMT.
  26.  
  27. $Log:    Time.c,v $
  28.  * Revision 3.0  90/05/20  00:21:44  kgorlen
  29.  * Release for 1st edition.
  30.  * 
  31. */
  32.  
  33. #include "Date.h"
  34. #include "Time.h"
  35. #include "nihclconfig.h"
  36. #include "nihclIO.h"
  37. #include <iomanip.h>
  38.  
  39. const unsigned VERSION =2;
  40.  
  41. #define    THIS    Time
  42. #define    BASE    Object
  43.  
  44. #ifdef SYSV && ! defined(hpux)
  45.  
  46. #include <time.h>
  47. #define TIME_ZONE timezone
  48. #define DST_OBSERVED daylight
  49. #define BASE_CLASSES BASE::desc()
  50. #define MEMBER_CLASSES
  51. #define VIRTUAL_BASE_CLASSES Object::desc()
  52.  
  53. DEFINE_CLASS(Time,VERSION,"$Header: /afs/alw.nih.gov/unix/sun4_40c/usr/local/src/nihcl-3.0/share/lib/RCS/Time.c,v 3.0 90/05/20 00:21:44 kgorlen Rel $",NULL,NULL);
  54.  
  55. #endif
  56.  
  57. #ifdef BSD || defined(hpux)
  58.  
  59. #ifdef hpux
  60. #include <time.h>
  61. #else
  62. #include <sys/time.h>
  63. #endif
  64.  
  65. static long TIME_ZONE;          /* seconds west of GMT */
  66. static int DST_OBSERVED;        /* flags U.S. daylight saving time observed */
  67.  
  68. static void inittimezone(const Class&) {
  69.     struct timeval tval;            /* see <sys/time.h> */
  70.     struct timezone tz;             /* see <sys/time.h> */
  71.     gettimeofday(&tval,&tz);
  72.     TIME_ZONE = 60*(tz.tz_minuteswest);
  73.     DST_OBSERVED = tz.tz_dsttime;
  74. }
  75.  
  76. #define BASE_CLASSES BASE::desc()
  77. #define MEMBER_CLASSES
  78. #define VIRTUAL_BASE_CLASSES Object::desc()
  79.  
  80. DEFINE_CLASS(Time,VERSION,"$Header: /afs/alw.nih.gov/unix/sun4_40c/usr/local/src/nihcl-3.0/share/lib/RCS/Time.c,v 3.0 90/05/20 00:21:44 kgorlen Rel $",inittimezone,NULL);
  81.  
  82. #endif
  83.  
  84. extern const int NIHCL_DATERANGE,NIHCL_BADTIME;
  85.  
  86. static const unsigned long seconds_in_day = 24*60*60;
  87. static const Date refDate(0L);
  88. static const Date maxDate(49709L);    /* ((2**32)-1)/seconds_in_day -1 */
  89.     
  90. Time Time::localTime(const Date& date, hourTy h, minuteTy m, secondTy s)
  91. /*
  92.     Return a local Time for the specified Standard Time date, hour, minute,
  93.     and second.
  94. */
  95. {
  96.     if (!date.between(refDate,maxDate))
  97.         setError(NIHCL_DATERANGE,DEFAULT,
  98.             date.dayOfMonth(),date.nameOfMonth(),date.year());
  99.     return Time(seconds_in_day*(date-refDate) + 60*60*h + 60*m + s);
  100. }
  101.  
  102. Time::Time()
  103. /*
  104.     Construct a Time for this instant.
  105. */
  106. {
  107.     sec = time(0);
  108.     sec += 2177452800L;    /* seconds from 1/1/01 to 1/1/70 */
  109. }
  110.  
  111. Time::Time(hourTy h, minuteTy m, secondTy s, bool dst)
  112. /*
  113.     Construct a Time for today at the specified (local) hour, minute, and
  114.     second.
  115. */
  116. {
  117.     sec = Time(Date(),h,m,s,dst).sec;
  118. }
  119.  
  120.  
  121. Time::Time(const Date& date, hourTy h, minuteTy m, secondTy s, bool dst)
  122. /*
  123.     Construct a Time for the specified (local) Date, hour, minute, and
  124.     second.
  125. */
  126. {
  127.     sec = localTime(date,h,m,s).sec-3600;
  128.     if (isDST()) {
  129.         sec += 3600;
  130.         if (isDST() || dst) sec -= 3600;
  131.     }
  132.     else {
  133.         sec += 3600;
  134.         if (isDST()) setError(NIHCL_BADTIME,DEFAULT,
  135.             date.dayOfMonth(),date.nameOfMonth(),date.year(),
  136.             h,m,s,(dst?"DST":""));
  137.     }
  138.     sec += TIME_ZONE;                // adjust to GMT 
  139. }
  140.  
  141. Time::operator Date() const
  142. /*
  143.     Convert a Time to a local Date
  144. */
  145. {
  146. //    return Date((int)(localTime().sec/seconds_in_day));    4.2 cc bug
  147.     long daycount = (long)(localTime().sec/seconds_in_day);
  148.     return Date(daycount);
  149. }
  150.  
  151. bool Time::between(const Time& a, const Time& b) const
  152. {
  153.     return *this >= a && *this <= b;
  154. }
  155.  
  156. hourTy Time::hour() const
  157. /*
  158.     Return the hour of this Time in local time; i.e., adjust for
  159.     time zone and Daylight Savings Time.
  160. */
  161. {
  162.     return localTime().hourGMT();
  163. }
  164.  
  165. hourTy Time::hourGMT() const
  166. /*
  167.     Return the hour of this Time in GMT.
  168. */
  169. {
  170.     return (sec % 86400) / 3600;
  171. }
  172.  
  173. Time Time::beginDST(unsigned year)
  174. /*
  175.     Return the local Standard Time at which Daylight Savings Time
  176.     begins in the specified year.
  177. */
  178. {
  179.     Time DSTtime(localTime(Date(31,"Mar",year).previous("Sun")+7,2));
  180.     if (year<=1986) {
  181.         DSTtime = localTime(Date(30,"Apr",year).previous("Sun"),2);
  182.         if (year==1974) DSTtime = localTime(Date(6,"Jan",1974),2);
  183.         if (year==1975) DSTtime = localTime(Date(23,"Feb",1975),2);
  184.     }
  185.     return DSTtime;
  186. }
  187.  
  188. Time Time::endDST(unsigned year)
  189. /*
  190.     Return the local Standard Time at which Daylight Savings Time
  191.     ends in the specified year.
  192. */
  193. {
  194.     Time STDtime(localTime(Date(31,"Oct",year).previous("Sun"),2-1));
  195.     return STDtime;
  196. }
  197.  
  198. bool Time::isDST() const
  199. /*
  200.     Return YES if this local Standard Time should be adjusted
  201.     for Daylight Savings Time.
  202. */
  203. {
  204. //    unsigned year = Date((unsigned)(this->sec/seconds_in_day)).year();  4.2 cc bug
  205.     long daycount = (long)(this->sec/seconds_in_day);
  206.     unsigned year = Date(daycount).year();
  207. #ifdef BUGbC3035
  208. // sorry, not implemented: temporary of class <name> with destructor needed in <expr> expression
  209.     if (DST_OBSERVED && *this >= beginDST(year) && *this < endDST(year))
  210.         return YES;
  211. #else
  212.     if (DST_OBSERVED)
  213.         if (*this >= beginDST(year))
  214.             if (*this < endDST(year)) return YES;
  215. #endif
  216.     return NO;
  217. }
  218.  
  219. Time Time::localTime() const
  220. /*
  221.     Adjusts this GM Time for local time zone and Daylight Savings Time.
  222. */
  223. {
  224.     Time local_time(sec-TIME_ZONE);
  225.     if (local_time.isDST()) local_time.sec += 3600;
  226.     return local_time;
  227. }
  228.  
  229. minuteTy Time::minute() const
  230. /*
  231.     Return the minute of this Time in local time; i.e., adjust
  232.     for time zone and Daylight Savings Time.
  233. */
  234. {
  235.     return localTime().minuteGMT();
  236. }
  237.  
  238. minuteTy Time::minuteGMT() const
  239. /*
  240.     Return the minute of this Time in GMT.
  241. */
  242. {
  243.     return ((sec % 86400) % 3600) / 60;
  244. }
  245.  
  246. secondTy Time::second() const
  247. /*
  248.     Return the second of this Time.
  249. */
  250. {
  251.     return ((sec % 86400) % 3600) % 60;
  252. }
  253.  
  254. Time Time::max(const Time& t) const
  255. {
  256.     if (t < *this) return *this;
  257.     return t;
  258. }
  259.  
  260. Time Time::min(const Time& t) const
  261. {
  262.     if (t > *this) return *this;
  263.     return t;
  264. }
  265.  
  266. int Time::compare(const Object& ob) const
  267. {
  268.     assertArgSpecies(ob,classDesc,"compare");
  269.     register clockTy t = castdown(ob).sec;
  270.     if (sec < t) return -1;
  271.     if (sec > t) return 1;
  272.     return 0;
  273. }
  274.  
  275. void Time::deepenShallowCopy()    {}
  276.  
  277. unsigned Time::hash() const    { return sec; }
  278.  
  279. bool Time::isEqual(const Object& ob) const
  280. {
  281.     return ob.isSpecies(classDesc) && *this==castdown(ob);
  282. }
  283.  
  284. const Class* Time::species() const { return &classDesc; }
  285.  
  286. void Time::printOn(ostream& strm) const
  287. {
  288.     register unsigned hh = hour();
  289.     Date(*this).printOn(strm);
  290.      strm << ' ' << ((hh <= 12) ? hh : hh-12) << ':'
  291.           << setfill('0') << setw(2) << minute() << ':'
  292.           << setfill('0') << setw(2) << second() << ' ';
  293.     if (hh < 12) strm << "am";
  294.     else strm << "pm";
  295. }
  296.  
  297. Time::Time(OIOin& strm)
  298.     : BASE(strm)
  299. {
  300.     unsigned long usec;
  301.     strm >> sec >> usec;
  302. }
  303.  
  304. void Time::storer(OIOout& strm) const
  305. {
  306.     BASE::storer(strm);
  307.     strm << sec << 0l /* for future usec */;
  308. }
  309.  
  310.  
  311. Time::Time(OIOifd& fd)
  312.     : BASE(fd)
  313. {
  314.     unsigned long usec;
  315.     fd >> sec >> usec;
  316. }
  317.  
  318. void Time::storer(OIOofd& fd) const
  319. {
  320.     BASE::storer(fd);
  321.     fd << sec << 0l /* for future usec */;
  322. }
  323.